package MemoryManagement.Test;

import MemoryManagement.*;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

import java.util.ArrayList;
import java.util.Map;
import java.util.concurrent.atomic.AtomicInteger;

import static MemoryManagement.MemoryManagement.bitMap;
import static org.junit.jupiter.api.Assertions.*;

class MMUTest {

    MemoryManagementImpl memoryManager;

    @BeforeEach
    void setUp() {
        memoryManager = new MemoryManagementImpl();
        memoryManager.InitMemory(); // 初始化内存
    }


    @Test
    void init_TLBInitialized_TLBSizeCorrect() {
        // Arrange & Act
        int expectedTLBSize = 10;
        int actualTLBSize = MMU.TLB.size();

        // Assert
        assertEquals(expectedTLBSize, actualTLBSize);
    }

    @Test
    void freeTLB_validRegister_TLBCleared() {
        // Arrange
        int register = 0;
        Map<Integer, Item> itemMap = MMU.TLB.get(register);
        itemMap.put(0, new Item(0, 1, (byte) 0, (byte) 0, (byte) 0, (byte) 0));

        // Act
        MMU.FreeTLB(register);

        // Assert
        assertTrue(itemMap.isEmpty());
    }

    @Test
    void translateAddress_validInput_successfulTranslation() {
        // Arrange
        int PID = 1;
        int size = 1024; // 假设要分配的大小为一页

        // Act
        int register = memoryManager.Allocate(PID, size);


        int logicalAddress = (22 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress2 = (23 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress3 = (24 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress4 = (25 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123

        AtomicInteger block = new AtomicInteger(0);
        AtomicInteger startOffset = new AtomicInteger(0);
        int modify = 0;


        // Act
        int result = MMU.translateAddress(register, logicalAddress, block, startOffset, modify);
        if (result == MemoryManagement.PAGE_FAULT)
            memoryManager.PageFaultProcess(register, logicalAddress, block.get());


        int result2 = MMU.translateAddress(register, logicalAddress2, block, startOffset, modify);
        if (result == MemoryManagement.PAGE_FAULT)
            memoryManager.PageFaultProcess(register, logicalAddress2, block.get());

        int result3 = MMU.translateAddress(register, logicalAddress3, block, startOffset, modify);
        if (result == MemoryManagement.PAGE_FAULT)
            memoryManager.PageFaultProcess(register, logicalAddress3, block.get());

        int result4 = MMU.translateAddress(register, logicalAddress4, block, startOffset, modify);
        if (result == MemoryManagement.PAGE_FAULT)
            memoryManager.PageFaultProcess(register, logicalAddress4, block.get());

        int result5 = MMU.translateAddress(register, logicalAddress, block, startOffset, modify);
        if (result5 == MemoryManagement.PAGE_FAULT)
            memoryManager.PageFaultProcess(register, logicalAddress, block.get());
//        // Assert
//        assertEquals(MemoryManagement.PAGE_FAULT, result);
//        assertEquals(0,block.get());
//        PageTable pageTable = new PageTable(Memory.readPage(register,0,Memory.pageSize));
//        ArrayList<Item> table = pageTable.getPageTable();
//        assertEquals(0,table.get(0).getState());
//        assertEquals(10,table.get(0).getBlock());


//        PageTable newPageTable = new PageTable(Memory.readPage(register,0,Memory.pageSize));
//        ArrayList<Item> newTable = newPageTable.getPageTable();
//        assertEquals(0,newTable.get(0).getState());
//        assertEquals(-1,newTable.get(0).getBlock());
//
//        assertEquals(1,newTable.get(22).getState());
//        assertEquals(10,newTable.get(22).getBlock());
//
//
//
//        // Assert
//        assertEquals(MemoryManagement.SUCCESS, result2);
//        assertEquals(10,block.get());


    }


    @Test
    void translateAddress_validInput_successfulTranslationSeq() {
        int PID = 27;
        int size = 1024; // 假设要分配的大小为一页

        // Act
        int register = memoryManager.Allocate(PID, size);

//        for(int i=0;i<Memory.pageNums;i++){
//            if (bitMap[i][0]==PID&&bitMap[i][1]==-1) System.out.println(i);
//        }


        int logicalAddress1 = (2 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress2 = (4 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress3 = (5 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress4 = (2 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress5 = (7 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress6 = (3 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress7 = (6 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress8 = (1 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress9 = (9 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress10 = (2 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123
        int logicalAddress11 = (4 << 10) + 123; // 构造逻辑地址，其中页号为22，页内偏移为123

        AtomicInteger block = new AtomicInteger(0);
        AtomicInteger startOffset = new AtomicInteger(0);
        int modify = 0;


        // Act
        int result1 = MMU.translateAddress(register, logicalAddress1, block, startOffset, modify);
        if (result1 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress1, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();

        // Act
        int result2 = MMU.translateAddress(register, logicalAddress2, block, startOffset, modify);
        if (result2 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress2, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();

        // Act
        int result3 = MMU.translateAddress(register, logicalAddress3, block, startOffset, modify);
        if (result3 == MemoryManagement.PAGE_FAULT) {
            System.out.println(block.get());
            memoryManager.PageFaultProcess(register, logicalAddress3, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();

        // Act
        int result4 = MMU.translateAddress(register, logicalAddress4, block, startOffset, modify);
        if (result4 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress4, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();


        // Act
        int result5 = MMU.translateAddress(register, logicalAddress5, block, startOffset, modify);
        if (result5 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress5, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();


        // Act
        int result6 = MMU.translateAddress(register, logicalAddress6, block, startOffset, modify);
        if (result6 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress6, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();


        // Act
        int result7 = MMU.translateAddress(register, logicalAddress7, block, startOffset, modify);
        if (result7 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress7, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();


        // Act
        int result8 = MMU.translateAddress(register, logicalAddress8, block, startOffset, modify);
        if (result8 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress8, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();


        // Act
        int result9 = MMU.translateAddress(register, logicalAddress9, block, startOffset, modify);
        if (result9 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress9, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();


        // Act
        int result10 = MMU.translateAddress(register, logicalAddress10, block, startOffset, modify);
        if (result10 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress10, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();


        // Act
        int result11 = MMU.translateAddress(register, logicalAddress11, block, startOffset, modify);
        if (result11 == MemoryManagement.PAGE_FAULT) {
            memoryManager.PageFaultProcess(register, logicalAddress11, block.get());
            System.out.println("缺页："+block.get());
        }else {
            System.out.println(block.get());
        }
        System.out.println();



    }
}
